/* 
 * @(#)PrivilegioBean.java 
 *  
 * Esta clase presenta la informacion de un rol  
 * 
 * @version 1.0
 * @date 01/11/12 
 * @author Nelson Chicas
 *  
 */
package muhnes.sizoo.controlador;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import muhnes.sizoo.dal.FabricaDAO;
import muhnes.sizoo.dal.RolDao;
import muhnes.sizoo.dal.UsuarioDao;
import muhnes.sizoo.modelo.Otorgamiento;
import muhnes.sizoo.modelo.Rol;
import muhnes.sizoo.modelo.Usuario;
import muhnes.sizoo.util.Transaccion;
import muhnes.sizoo.util.Utilidades;
import org.apache.commons.codec.digest.DigestUtils;

/**
 * Clase que contiene los metodos que controlan la vista de usuarios
 * @author Nelson Chicas
 */
@ManagedBean(name = "usuarioBean")
@ViewScoped
public class UsuarioBean extends CRUDBean< Usuario, UsuarioDao > 
    implements Serializable {
    
    @ManagedProperty(value="#{correoBean}")
    private CorreoBean correoBean;
    
    private List< Rol > listaRoles;
    private List< SelectItem > itemsRoles;
    private List< SelectItem > itemsTrabajadores;

    /**
     * Constructor de la clase
     */
    public UsuarioBean() {
        super( Usuario.class );
        vistaProtegida = "usuario";
    }
    
    /**
     * Setter de correoBean
     * @param correoBean 
     */
    public void setCorreoBean( CorreoBean correoBean ) {
        this.correoBean = correoBean;
    }
    
    /**
     * Getter de listaRoles
     *  
     */
    public List< Rol > getListaRoles() {
        if( listaRoles == null ) {
            RolDao dao = FabricaDAO.crearRolDao();
            listaRoles = dao.buscarTodos();
        }
        return listaRoles;
    }
    
    /**
     * Metodo que obtiene una lista de roles
     * @return objeto list
     */
    public List< SelectItem > getItemsRoles() {
        if( itemsRoles == null ) {
            itemsRoles = new ArrayList< SelectItem >();
            RolDao dao = FabricaDAO.crearRolDao();
            for( Rol rol : dao.buscarTodos() ) {
                SelectItem item = new SelectItem( rol, rol.getNombre() );
                itemsRoles.add( item );
            }
        }
        return itemsRoles;
    }
    
    /**
     * Obtiene una lista de trabajadores
     * @return objeto list
     */
    public List< SelectItem > getItemsTrabajadores() {
        if( itemsTrabajadores == null ) {
            itemsTrabajadores = new ArrayList< SelectItem >();
            UsuarioDao dao = FabricaDAO.crearUsuarioDao();
            for( Usuario trabajador : dao.buscarTodos() ) {
                String nombre = trabajador.getNombre();
                SelectItem item = new SelectItem( nombre, nombre );
                itemsTrabajadores.add( item );
            }
        }
        return itemsTrabajadores;
    }
    
    public SelectItem[] getItemsEstados() {
        SelectItem[] itemsEstados = new SelectItem[5];
        itemsEstados[0] = new SelectItem( "", "Todos" );
        itemsEstados[1] = new SelectItem( "Validando", "Validando" );
        itemsEstados[2] = new SelectItem( "Activo", "Activo" );
        itemsEstados[3] = new SelectItem( "Bloqueado", "Bloqueado" );
        itemsEstados[4] = new SelectItem( "Eliminado", "Eliminado" );
        return itemsEstados;
    }
    
    /**
     * Metodo que obtiene una lista de roles de usuario
     *  
     */
    public List<Rol> getRolesUsuario() {
        List<Rol> rolesUsuario = new ArrayList<Rol>();
        for( Rol rol : entidad.getRoles() ) {
            rolesUsuario.add( rol );
        }
        return rolesUsuario;
    }
    
    /**
     * Selecciona los roles de usuario
     * @param roles 
     */
    public void setRolesUsuario( List<Rol> roles ) {
        Set<Rol> rolesUsuario = new HashSet<Rol>();
        for( Rol rol : roles ) {
            rolesUsuario.add( rol );
        }
        entidad.setRoles(rolesUsuario);
    }
    
    /**
     * Metodo que filtra los usuarios
     * @param filtro
     * @return objeto list
     */
    public List< String > filtrarUsuarios( String filtro ) {
        CharSequence secuencia = filtro;
        List< String > usuariosFiltrados = new ArrayList< String >();
        for( Usuario trabajador : listaEntidades ) {
            if( trabajador.getNombre().contains( secuencia ) ) {
                usuariosFiltrados.add( trabajador.getNombre() );
            }
        }
        return usuariosFiltrados;
    }
    
    /**
     * Metodo que btiene una lista de roles de usuario
     * @param usuarioSeleccionado
     * @return objeto list 
     */
    public List<Rol> obtenerRoles( Usuario usuarioSeleccionado ) {
        List<Rol> rolesUsuario = new ArrayList<Rol>();
        for( Rol rol : usuarioSeleccionado.getRoles() ) {
            rolesUsuario.add( rol );
        }
        return rolesUsuario;
    }
    
    /**
     * Metodo que asigna los roles al usuario
     * @param usuarioSeleccionado
     * @param roles 
     */
    public void asignarRoles( Usuario usuarioSeleccionado, List<Rol> roles ) {
        Set<Rol> rolesUsuario = new HashSet<Rol>();
        for( Rol rol : roles ) {
            rolesUsuario.add( rol );
        }
        usuarioSeleccionado.setRoles(rolesUsuario);
    }
    
    /**
     * Metodo que remueve el rol al usuario
     * @param usuarioSeleccionado
     * @param rol 
     */
    public void revocarRol( Usuario usuarioSeleccionado, Rol rol ) {
        usuarioSeleccionado.getRoles().remove(rol);
        UsuarioDao dao = FabricaDAO.crearUsuarioDao();
        dao.actualizar( usuarioSeleccionado );
    }

    /**
     * Metodo que agrega un nuevo usuario
     * @param event 
     */
    @Override
    public void agregarEntidad ( ActionEvent event ){
        UsuarioDao dao = FabricaDAO.crearUsuarioDao();
        
        boolean confirmacionEnviada = enviarCorreoRegistro();
        if( confirmacionEnviada ) {
            entidad.setEstado("Activo");
        }
        else {
            entidad.setEstado("Validando");
        }
          
        String frase = Utilidades.crearFrase( 48 );
        entidad.setFrase(frase);
        
        String contrasenyaMd5 = DigestUtils.md5Hex( entidad.getContrasenya() + frase );
        entidad.setContrasenya( contrasenyaMd5 );
        
        dao.guardar( entidad );
        recrearModelo();
    }
    
    /**
     * Metodo que elimina un usuario
     * @param event 
     */
    @Override
    public void eliminarEntidad ( ActionEvent event ){
        if( !validarDependencia() ) {
            return;
        }
        
        UsuarioDao dao = FabricaDAO.crearUsuarioDao();
        entidad.getRoles().clear();
        entidad.setEstado( "Eliminado" );
        dao.actualizar(entidad);
        recrearModelo();
    }
    
    /**
     * Metodo que actualiza el rol del usuario
     * @param otorgamiento 
     */
    public void actualizarRol( Otorgamiento otorgamiento ) {
        entidad.setOtorgamiento(otorgamiento);
        UsuarioDao usuarioDao = FabricaDAO.crearUsuarioDao();
        usuarioDao.actualizar( entidad );
        recrearModelo();
    }
    
    /**
     * Metodo que restaura la contraseña del usuario
     */
    public void restaurarContrasenya() {
        String frase = Utilidades.crearFrase( 48 );
        entidad.setFrase( frase );
        String contrasenyaMd5 = DigestUtils.md5Hex( entidad.getContrasenya() + frase );
        entidad.setContrasenya( contrasenyaMd5 );
        
        UsuarioDao dao = FabricaDAO.crearUsuarioDao();
        dao.guardar( entidad );
    }
    
    /**
     * Metodo que envia correo electronico
     *  
     */
    private boolean enviarCorreoRegistro() {
        
        correoBean.setAsunto( "Confirmación de registro" );
        correoBean.setContenido( "Usuario: " + entidad.getCorreousuario() + "\nContraseña: " + entidad.getContrasenya() );
        correoBean.enviarCorreo( entidad.getCorreousuario() );
        
        return true;
        
    }

    /**
     * Metodo que instancia un nuevo UsuarioDAO
     */
    @Override
    protected UsuarioDao getDAO () {
        return FabricaDAO.crearUsuarioDao();
    }
    
    /**
     * 
     * @param transaccion indica que transaccion se debera realizar 
     * @return objeto de tipo boolean que indica que tipo de transaccion se realizara
     */
    @Override
    protected boolean debeValidar ( Transaccion transaccion ) {
        boolean validacion = false;
        
        switch( transaccion ) {
            case INSERCION:
            case ELIMINACION:
                validacion = true;
        }
        
        return validacion;
    }

}


